package cn.jeasy.core.util;


import java.beans.PropertyDescriptor;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 字符串工具类
 * @author Fred
 *
 */
public class StringUtil {
	private static final Logger logger = LoggerFactory.getLogger(StringUtil.class);
	public static String UTF_8="utf-8";
	private static final Pattern pattern = Pattern.compile("#\\{(.*?)\\}");
	/**
     * 字符串分隔符
     */
    public static final String SEPARATOR = String.valueOf((char) 29);
    
	
	/**
	 * 是否非空
	 * @param str
	 * @return
	 */
	public static boolean isNotEmpty(String str){		
		return str!=null&&str.length()>0;
	}
	/**
	 * 是否空字符
	 * @param str
	 * @return
	 */
	public static boolean isNullOrEmpty(String str){		
		return !isNotEmpty(str);
	}
	/**
	 * 字符串为空时用默认值
	 * @param str
	 * @param defaultStr 默认值
	 * @return
	 */
	public static String defaultIfEmpty(String str, String defaultStr) {
	     return isNotEmpty(str)?str:defaultStr;
	}
	  /**
     * 分割固定格式的字符串
     */
    public static String[] splitString(String str, String separator) {
        return StringUtils.splitByWholeSeparator(str, separator);
    }
    /**
     * 替换固定格式的字符串（支持正则表达式）
     */
    public static String replaceAll(String str, String regex, String replacement) {
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (m.find()) {
            m.appendReplacement(sb, replacement);
        }
        m.appendTail(sb);
        return sb.toString();
    }

    /**
     * 是否为数字（整数或小数）
     */
    public static boolean isNumber(String str) {
        return NumberUtils.isNumber(str);
    }

    /**
     * 是否为十进制数（整数）
     */
    public static boolean isDigits(String str) {
        return NumberUtils.isDigits(str);
    }

    /**
     * 将驼峰风格替换为下划线风格
     */
    public static String camelhumpToUnderline(String str) {
        Matcher matcher = Pattern.compile("[A-Z]").matcher(str);
        StringBuilder builder = new StringBuilder(str);
        for (int i = 0; matcher.find(); i++) {
            builder.replace(matcher.start() + i, matcher.end() + i, "_" + matcher.group().toLowerCase());
        }
        if (builder.charAt(0) == '_') {
            builder.deleteCharAt(0);
        }
        return builder.toString();
    }

    /**
     * 将下划线风格替换为驼峰风格
     */
    public static String underlineToCamelhump(String str) {
        Matcher matcher = Pattern.compile("_[a-z]").matcher(str);
        StringBuilder builder = new StringBuilder(str);
        for (int i = 0; matcher.find(); i++) {
            builder.replace(matcher.start() - i, matcher.end() - i, matcher.group().substring(1).toUpperCase());
        }
        if (Character.isUpperCase(builder.charAt(0))) {
            builder.replace(0, 1, String.valueOf(Character.toLowerCase(builder.charAt(0))));
        }
        return builder.toString();
    }


    /**
     * 将字符串首字母大写
     */
    public static String firstToUpper(String str) {
        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    }

    /**
     * 将字符串首字母小写
     */
    public static String firstToLower(String str) {
        return Character.toLowerCase(str.charAt(0)) + str.substring(1);
    }

	


	/**
	 * 格式化字符串 字符串中使用#{key}表示占位符
	 * 
	 * @param sourStr   需要匹配的字符串
	 * @param param     参数集
	 * @return
	 */
	public static String stringFormat(String sourStr, Map<String, Object> param) {
	    String tagerStr = sourStr;
	    if (param == null)  return tagerStr;
	     Matcher matcher = pattern.matcher(tagerStr);
	    while (matcher.find()) {
	        String key = matcher.group();
	        String keyclone = key.substring(2, key.length() - 1).trim();
	        Object value = param.get(keyclone);
	        if (value != null)
	            tagerStr = tagerStr.replace(key, value.toString());
	    }
	    return tagerStr;
	}

	/**
	 * 格式化字符串 字符串中使用#{key}表示占位符 利用反射 自动获取对象属性值 (必须有get方法)
	 * 
	 * @param sourStr   需要匹配的字符串
	 * @param param   参数集
	 * @return
	 */
	public static String stringFormat(String sourStr, Object obj) {
	    String tagerStr = sourStr;
	    Matcher matcher = pattern.matcher(tagerStr);
	    if (obj == null)
	        return tagerStr;

	    PropertyDescriptor pd;
	    Method getMethod;
	    // 匹配#{}中间的内容 包括括号
	    while (matcher.find()) {
	        String key = matcher.group();
	        String keyclone = key.substring(2, key.length() - 1).trim();
	        try {
	            pd = new PropertyDescriptor(keyclone, obj.getClass());
	            getMethod = pd.getReadMethod();// 获得get方法
	            Object value = getMethod.invoke(obj);
	            if (value != null)
	                tagerStr = tagerStr.replace(key, value.toString());
	        } catch (Exception e) {
	            
	        }
	    }
	    return tagerStr;
	}

	/**
	 * 格式化字符串 (替换所有) 字符串中使用#{key}表示占位符
	 * 
	 * @param sourStr   需要匹配的字符串
	 * @param param   参数集
	 * @return
	 */
	public static String stringFormatAll(String sourStr, Map<String, Object> param) {
	    String tagerStr = sourStr;
	    if (param == null)
	        return tagerStr;
	    Matcher matcher = pattern.matcher(tagerStr);
	    while (matcher.find()) {
	        String key = matcher.group();
	        String keyclone = key.substring(2, key.length() - 1).trim();
	        Object value = param.get(keyclone);
	        if (value != null)
	            tagerStr = tagerStr.replace(key, value.toString());
	    }
	    return tagerStr;
	}
	

    /**
     * 将 URL 编码
     */
    public static String encodeURL(String str) {
        String target;
        try {
            target = URLEncoder.encode(str, UTF_8);
        } catch (Exception e) {
            logger.error("编码出错！", e);
            throw new RuntimeException(e);
        }
        return target;
    }

    /**
     * 将 URL 解码
     */
    public static String decodeURL(String str) {
        String target;
        try {
            target = URLDecoder.decode(str, UTF_8);
        } catch (Exception e) {
            logger.error("解码出错！", e);
            throw new RuntimeException(e);
        }
        return target;
    }

    /**
     * 将字符串 Base64 编码
     */
    public static String encodeBASE64(String str) {
        String target;
        try {
            target = Base64.encodeBase64URLSafeString(str.getBytes(UTF_8));
        } catch (UnsupportedEncodingException e) {
            logger.error("编码出错！", e);
            throw new RuntimeException(e);
        }
        return target;
    }

    /**
     * 将字符串 Base64 解码
     */
    public static String decodeBASE64(String str) {
        String target;
        try {
            target = new String(Base64.decodeBase64(str), UTF_8);
        } catch (UnsupportedEncodingException e) {
            logger.error("解码出错！", e);
            throw new RuntimeException(e);
        }
        return target;
    }

    /**
     * 将字符串 MD5 加密
     */
    public static String encryptMD5(String str) {
        return DigestUtils.md5Hex(str);
    }

    /**
     * 将字符串 SHA 加密
     */
    public static String encryptSHA(String str) {
        return DigestUtils.sha1Hex(str);
    }

    /**
     * 创建随机数
     */
    public static String createRandom(int count) {
        return RandomStringUtils.randomNumeric(count);
    }

    /**
     * 获取 UUID（32位）
     */
    public static String createUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }
	
}
